#include <parse.hpp>
#include <bex/bex.hpp>
#include <algorithm>    // std::transform
#include <baltam.hpp>

std::string GetFileName(const bxArray *p) {
    std::string filename;
    // 检查 filename 为字符串
    if (IsString(p)) {
        // bxAsString(const bxArray*) 将给定的 bxArray 对象转化为 string 对象
        filename = baltam::bxAsString(p);
    } else {
        bxErrMsgTxt("\"filename\" 必须为字符串标量或字符向量!");
    }
    return filename;
}

std::string GetParameterName(const bxArray *p) {
    std::string parameter;
    if (IsString(p)) {
        parameter = baltam::bxAsString(p);
    } else {
        bxErrMsgTxt("需要字符串标量或字符向量形式的参数名称!");
    }
    // 全部转化为小写
    // https://blog.csdn.net/qq_31186409/article/details/50545682
    std::transform(parameter.begin(), parameter.end(),
                   parameter.begin(), (int (*)(int))tolower);
    return parameter;
}

bool GetConsecutive(const bxArray *p) {
    bool consecutive;
    if (IsString(p)) {
        std::string str = baltam::bxAsString(p);
        if (str == "join") {
            consecutive = true;
        } else if (str == "split") {
            consecutive = false;
        } else {
            std::string info = 
                "输入应与以下值之一匹配:\n\n"
                "'split', 'join'\n\n"
                "输入 '" + str + "' 与任何有效值均不匹配!";
            bxErrMsgTxt(info.c_str());
        }
    } else {
        std::string info =
            "输入应为以下类型之一:\n\n"
            "char, string\n\n"
            "但其类型为 " + GetTypeString(p) + "!";
        bxErrMsgTxt(info.c_str());
    }
    return consecutive;
}

bool GetLeadingRule(const bxArray *p) {
    bool ignore;
    if (IsString(p)) {
        std::string str = baltam::bxAsString(p);
        if (str == "ignore") {
            ignore = true;
        } else if (str == "keep") {
            ignore = false;
        } else {
            std::string info = 
                "输入应与以下值之一匹配:\n\n"
                "'ignore', 'keep'\n\n"
                "输入 '" + str + "' 与任何有效值均不匹配!";
            bxErrMsgTxt(info.c_str());
        }
    } else {
        std::string info =
            "输入应为以下类型之一:\n\n"
            "char, string\n\n"
            "但其类型为 " + GetTypeString(p) + "!";
        bxErrMsgTxt(info.c_str());
    }
    return ignore;
}

int16_t GetNumHeaderLines(const bxArray *p) {
    // baInt bxAsInt(const bxArray*, int*) 尝试将给定 bxArray 对象转化为内置整数
    int err = 1;     // 表示 bxAsInt 转化是否成功. 0 表示成功, 1 表示失败.
    int16_t num = bxAsInt(p, &err);
    if (err == 1 || num < 0) {
        bxErrMsgTxt("必须为非负整数标量值!");
    }
    return num;
}
